// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "Communication/Socket/VmiSocket.h"
#include "Log/logging.h"
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <linux/in.h>
#include <linux/tcp.h>
#include <sys/socket.h>
#include <unistd.h>

using namespace std;

/**
 * @功能描述：默认构造函数
 */
VmiSocket::VmiSocket()
    : m_fd(INVALID_FD), m_status(SOCKET_STATUS_INIT), m_remoteIp(0), m_remotePort(0), m_localIp(0), m_localPort(0),
      m_socketOption(0), m_eventNotice(nullptr)
{
}

/**
 * @功能描述：带参构造函数
 * @参数 [in] fd：套接字句柄
 * @参数 [in] address：IP地址、端口
 * @参数 [in] socketOption：套接字选项
 */
VmiSocket::VmiSocket(int fd, const VmiSocketAddressGroup& address, unsigned int socketOption)
    : m_fd(fd), m_status(SOCKET_STATUS_INIT),  m_remoteIp(address.m_remoteIp), m_remotePort(address.m_remotePort),
      m_localIp(address.m_localIp), m_localPort(address.m_localPort), m_socketOption(socketOption),
      m_eventNotice(nullptr)
{
}

/*
 * @功能描述：通知socket断开
 */
void VmiSocket::EventNotice()
{
    if (m_eventNotice == nullptr) {
        INFO("m_eventNotice == nullptr");
        return;
    }
    m_eventNotice->Notice(shared_from_this());
}

/*
 * @功能描述：注册socket断开通知
 * @参数 [in] eventNotice：处理socket断开的VmiEventNotice对象智能指针
 */
void VmiSocket::SetEventNotice(std::shared_ptr<VmiEventNotice> eventNotice)
{
    m_eventNotice = eventNotice;
}

/*
 * @功能描述：设置socket句柄
 * @参数 [in] fd：socket句柄
 */
void VmiSocket::SetFd(int fd)
{
    m_fd = fd;
    DBG("set fd(%d)", fd);
}

/*
 * @功能描述：获取socket句柄
 * @返回值：socket句柄
 */
int VmiSocket::GetFd()
{
    return m_fd;
}

/*
 * @功能描述：设置状态
 * @参数 [in] status：状态，参见VmiSocketStatus定义
 */
void VmiSocket::SetStatus(int status)
{
    m_status = status;
}

/*
 * @功能描述：获取状态
 * @返回值：状态，参见VmiSocketStatus定义
 */
int VmiSocket::GetStatus()
{
    return m_status;
}

/*
 * @功能描述：设置socket选项
 * @参数 [in] option：选项组合，参见VmiSocketOptionBitset定义
 */
void VmiSocket::SetSocketOption(unsigned int option)
{
    m_socketOption = option;
}

/*
 * @功能描述：获取当前的选项设置
 * @返回值：选项组合，参见VmiSocketOptionBitset定义
 */
unsigned int VmiSocket::GetSocketOption() const
{
    return m_socketOption;
}

/*
 * @功能描述：设置对端和本地的IP、端口地址
 * @参数 [in] remoteIp：联网的对端的IP
 * @参数 [in] remotePort：联网的对端的端口
 * @参数 [in] localIp：本地的IP
 * @参数 [in] localPort：本地的端口
 */
void VmiSocket::SetAddress(unsigned int remoteIp, unsigned short int remotePort, unsigned int localIp,
    unsigned short int localPort)
{
    m_remoteIp = remoteIp;
    m_remotePort = remotePort;
    m_localIp = localIp;
    m_localPort = localPort;
}

/*
 * @功能描述：获取对端和本地的IP、端口地址
 * @参数 [out] remoteIp：用来返回对端的IP
 * @参数 [out] remotePort：用来返回对端的端口
 * @参数 [out] localIp：用来返回本地的IP
 * @参数 [out] localPort：用来返回本地的端口
 */
void VmiSocket::GetAddress(unsigned int &remoteIp, unsigned short int &remotePort, unsigned int &localIp,
    unsigned short int &localPort)
{
    remoteIp = m_remoteIp;
    remotePort = m_remotePort;
    localIp = m_localIp;
    localPort = m_localPort;
}

